package com.spring.lo.framework.factory.support;

import com.spring.lo.framework.factory.BeanFactory;
import com.spring.lo.framework.factory.config.BeanDefinition;

/**
 * 抽象Bean工厂
 * 主要负责定制getBean的流程（模板方法），具体创建Bean或者获取BeanDefinition的细节，该类不负责
 * @author zhangbh
 * 2023-05-28 16:44
 **/
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {


    /**
     * 获取BeanDefinition
     * @param beanName 标识
     * @return BeanDefinition
     */
    protected abstract BeanDefinition getBeanDefinition(String beanName);

    /**
     * 创建Bean实例
     * @param bd BeanDefinition
     * @return Bean 实例
     */
    protected abstract Object createBean(BeanDefinition bd);


    @Override
    public Object getBean(String beanName) {
        // 1.尝试从容器中获取
        Object bean = getSingleton(beanName);
        // 2.当获取到直接返回
        if (bean != null) {
            return bean;
        }
        BeanDefinition bd = getBeanDefinition(beanName);
        if (bd == null) {
            System.out.println("加载不到类声明,beanName=" + beanName);
            return null;
        }
        // 3.获取不到，则从BeanDefinition中解析元信息，创建Bean实例
        bean = loadBean(bd);
        return bean;
    }

    private Object loadBean(BeanDefinition bd) {
        Object bean;
        if (bd.isSingleton()) {
            bean = createBean(bd);
            registerSingleton(bd.getBeanName(), bean);
        } else if (bd.isPrototype()) {
            bean = createBean(bd);
        } else {
            // 其他模式
            bean = createBean(bd);
        }
        return bean;
    }

}
